require 'nokogiri'
require 'builder'
require 'active_support'
require 'typhoeus'
begin
  require 'active_support/core_ext/object/to_query'
  require 'active_support/core_ext/module/delegation'
  require 'active_support/core_ext/hash/conversions'
rescue
end

require File.expand_path('../vast_api/attributes.rb', __FILE__)
require File.expand_path('../vast_api/attributes/entry.rb', __FILE__)
require File.expand_path('../vast_api/categories.rb', __FILE__)
require File.expand_path('../vast_api/categories/category.rb', __FILE__)
require File.expand_path('../vast_api/listings.rb', __FILE__)
require File.expand_path('../vast_api/listings/entry.rb', __FILE__)

class VastApi
  attr_accessor :api_url, :light

  def initialize(apikey=nil, cat=nil, opts = {})
    @api_url = opts[:api_url] || 'http://data.vast.com/'
    @light = opts[:light] || false
    @category = cat
    @query = { }
    @query['apikey'] = apikey if apikey
    @categories = {}
    @attributes = {}
    @listings = {}
  end

  def category!(cat)
    @category = cat
    self
  end

  def category(cat=nil)
    if cat.nil?
      @category
    else
      self.clone.category!(cat)
    end
  end

  def where!(options)
    @query = @query.merge(options)
    self
  end

  def where(options)
    self.clone.where!(options)
  end

  def api_key
    @query['apikey']
  end

  def api_key=(key)
    @query['apikey'] = key
  end

  def query
    q = @query.dup
    if light
      q['light'] = 'yes'
    else
      q.delete('light')
    end
    q.to_query
  end

  def api_query
    q = {}
    q['apikey'] = api_key if api_key
    q['light'] = 'yes' if light
    q.to_query
  end

  def listings
    raise ArgumentError, "No category was entered" if @category.nil? || @category.empty?
    @listings[opt_hash] ||= Listings.new(self)
  end

  def attributes
    raise ArgumentError, "No category was entered" if @category.nil? || @category.empty?
    @attributes[opt_hash] ||= Attributes.new(self)
  end

  def categories
    @categories[@api_key] ||= Categories.new(self)
  end

  def find(id)
    raise ArgumentError, "No category was entered" if @category.nil? || @category.empty?
    if id.nil? || id.empty?
      nil
    else
      Listings.get(self, "#{api_url}listings/#{id}/-/#{@category}?#{api_query}")
    end
  end

  def find!(id)
    raise ArgumentError, "No id was entered" if id.nil? || id.empty?
    self.find(id)
  end

  def self.find(id, cat)
    Listings.get(self, "#{api_url}listings/#{id}/-/#{cat}?#{api_query}")
  end

  def self.find_by_url(url)
    Listings.get(self, url)
  end

  def create_entry(entry)
    if entry.at_xpath('v:attribute')
      Attributes::Entry.new(self,entry)
    else
      Listings::Entry.new(self,entry)
    end
  end

  def opt_hash
    str = ''
    str << @category if @category
    str << @api_key if @api_key
    str << @query.hash.to_s if @query
    str.hash
  end
end

